#include "syntaxhighlighter.h"
#include <QDebug>
#include <QTextCursor>
#include <QTextCharFormat>
#include <QRegularExpression>
#include <QColor>
#include <iostream>

SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent)
    : QSyntaxHighlighter(parent)
{
    setupRule();
/*
    //光标所在行标淡蓝
    highlightFormat.setBackground(QColor("greenyellow"));

    //查找时高亮
    searchText.clear();
    searchFormat.setForeground(QColor("greenyellow"));
    searchFormat.setFontWeight(QFont::Bold);
*/
    //调试信息高亮设置
    debugFormat.setBackground(QColor("lightcoral"));
    //debugFormat.setFontWeight(QFont::Bold);
}

void SyntaxHighlighter::setupRule()
{
    // 标点符号加粗且标红
    punctuationFormat.setForeground(QColor(167, 29, 93));
    punctuationFormat.setFontWeight(QFont::Bold);
    punctuationPattern = QRegularExpression("[\\~\\!\\%\\^\\&\\*\\-\\+\\=;:\\<,\\.\\>\\/\\|]");
    rules.append({punctuationPattern, punctuationFormat});

    // 预处理命令标绿
    preprocessorFormat.setForeground(QColor(24, 54, 145));
    preprocessorPattern = QRegularExpression("#[^\n]*");
    rules.append({preprocessorPattern, preprocessorFormat});

    //括号标红加粗
    braceFormat.setForeground(QColor(99, 163, 92));
    //braceFormat.setFontWeight(QFont::Bold);
    bracePattern = QRegularExpression("[\\(\\)\\{\\}\\[\\]]");
    rules.append({bracePattern, braceFormat});

    // 关键字加粗
    QTextCharFormat keywordFormat;
    keywordFormat.setForeground(QColor(167, 29, 93));
    //keywordFormat.setFontWeight(QFont::Bold);

    // 添加关键字到规则
    QStringList keywordPattern;
    keywordPattern << "\\bchar\\b" << "\\bdouble\\b" << "\\bfloat\\b" << "\\bint\\b" << "\\blong\\b" << "\\bshort\\b"
                   << "\\bunsigned\\b" << "\\bsigned\\b" << "\\bstruct\\b" << "\\bunion\\b" << "\\bvoid\\b" << "\\benum\\b"
                   << "\\bfor\\b" << "\\bdo\\b" << "\\bwhile\\b" << "\\bbreak\\b" << "\\bcontinue\\b"
                   << "\\bif\\b" << "\\belse\\b" << "\\bgoto\\b"
                   << "\\bswitch\\b" << "\\bcase\\b" << "\\bdefault\\b"
                   << "\\bauto\\b" << "\\bextern\\b" << "\\bregister\\b" << "\\bstatic\\b"
                   << "\\bconst\\b" << "\\bsizeof\\b" << "\\btypedef\\b" << "\\bvolatile\\b"
                   << "\\breturn\\b" << "\\bclass\\b" << "\\bpublic\\b" << "\\bprivate\\b" << "\\bprotected\\b"
                   << "\\bvirtual\\b" << "\\bfriend\\b" << "\\binline\\b" << "\\bnamespace\\b" << "\\boperator\\b"
                   << "\\btemplate\\b" << "\\btypename\\b" << "\\btry\\b" << "\\bcatch\\b" << "\\bthrow\\b"
                   << "\\bnew\\b" << "\\bdelete\\b" << "\\bthis\\b" << "\\busing\\b";

    foreach (const QString &pattern, keywordPattern) {
        QRegularExpression rulePattern(pattern);
        Rule rule = {rulePattern, keywordFormat};
        rules.append(rule);
    }

    // 数字标紫色
    numberFormat.setForeground(QColor(0, 134, 179));
    numberPattern = QRegularExpression("\\b\\d+(\\.\\d+)?\\b");
    rules.append({numberPattern, numberFormat});

    // 双引号及以内标蓝色
    stringFormat.setForeground(QColor(24, 54, 145));
    stringFormat.setFontWeight(QFont::Bold);
    stringPattern = QRegularExpression("\".*?\"");
    rules.append({stringPattern, stringFormat});

    //单行注释标浅蓝
    commentFormat.setForeground(QColor("darkGray"));
    commentPattern = QRegularExpression("//[^\n]*");
    rules.append({commentPattern, commentFormat});

}

void SyntaxHighlighter::setupRuleDark() {
    // 标点符号加粗且标红
    punctuationFormat.setForeground(QColor(207, 142, 109));
    punctuationFormat.setFontWeight(QFont::Bold);
    punctuationPattern = QRegularExpression("[\\~\\!\\%\\^\\&\\*\\-\\+\\=;:\\<,\\.\\>\\/\\|]");
    rules.append({punctuationPattern, punctuationFormat});

    // 预处理命令标绿
    preprocessorFormat.setForeground(QColor(179, 174, 96));
    preprocessorPattern = QRegularExpression("#[^\n]*");
    rules.append({preprocessorPattern, preprocessorFormat});

    //括号标红加粗
    braceFormat.setForeground(QColor(23, 159, 255));
    //braceFormat.setFontWeight(QFont::Bold);
    bracePattern = QRegularExpression("[\\(\\)\\{\\}\\[\\]]");
    rules.append({bracePattern, braceFormat});

    // 关键字加粗
    QTextCharFormat keywordFormat;
    keywordFormat.setForeground(QColor(207, 142, 109));
    //keywordFormat.setFontWeight(QFont::Bold);

    // 添加关键字到规则
    QStringList keywordPattern;
    keywordPattern << "\\bchar\\b" << "\\bdouble\\b" << "\\bfloat\\b" << "\\bint\\b" << "\\blong\\b" << "\\bshort\\b"
                   << "\\bunsigned\\b" << "\\bsigned\\b" << "\\bstruct\\b" << "\\bunion\\b" << "\\bvoid\\b" << "\\benum\\b"
                   << "\\bfor\\b" << "\\bdo\\b" << "\\bwhile\\b" << "\\bbreak\\b" << "\\bcontinue\\b"
                   << "\\bif\\b" << "\\belse\\b" << "\\bgoto\\b"
                   << "\\bswitch\\b" << "\\bcase\\b" << "\\bdefault\\b"
                   << "\\bauto\\b" << "\\bextern\\b" << "\\bregister\\b" << "\\bstatic\\b"
                   << "\\bconst\\b" << "\\bsizeof\\b" << "\\btypedef\\b" << "\\bvolatile\\b"
                   << "\\breturn\\b" << "\\bclass\\b" << "\\bpublic\\b" << "\\bprivate\\b" << "\\bprotected\\b"
                   << "\\bvirtual\\b" << "\\bfriend\\b" << "\\binline\\b" << "\\bnamespace\\b" << "\\boperator\\b"
                   << "\\btemplate\\b" << "\\btypename\\b" << "\\btry\\b" << "\\bcatch\\b" << "\\bthrow\\b"
                   << "\\bnew\\b" << "\\bdelete\\b" << "\\bthis\\b" << "\\busing\\b";

    foreach (const QString &pattern, keywordPattern) {
        QRegularExpression rulePattern(pattern);
        Rule rule = {rulePattern, keywordFormat};
        rules.append(rule);
    }

    // 数字标紫色
    numberFormat.setForeground(QColor(42, 172, 184));
    numberPattern = QRegularExpression("\\b\\d+(\\.\\d+)?\\b");
    rules.append({numberPattern, numberFormat});

    // 双引号及以内标蓝色
    stringFormat.setForeground(QColor(106, 171, 115));
    stringFormat.setFontWeight(QFont::Bold);
    stringPattern = QRegularExpression("\".*?\"");
    rules.append({stringPattern, stringFormat});

    //单行注释标浅蓝
    commentFormat.setForeground(QColor(122, 126, 133));
    commentPattern = QRegularExpression("//[^\n]*");
    rules.append({commentPattern, commentFormat});

}

void SyntaxHighlighter::highlightBlock(const QString &text)
{
    // 获取当前块的行号
    int currentLineNumber = currentBlock().blockNumber();
/*
    // 先处理高亮行
    if (currentLineNumber == highlightLineNumber) {
        setFormat(0, text.length(), highlightFormat);
        }
    else {
            setFormat(0, text.length(), QTextCharFormat());  // 清除格式
        }
*/
    // 处理标点符号和其他规则
    foreach (const Rule &rule, rules) {
        if (rule.pattern.pattern() == preprocessorPattern.pattern()) {
            continue; // Skip preprocessor rules here
        }
        QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
        while (matchIterator.hasNext()) {
            QRegularExpressionMatch match = matchIterator.next();
            int start = match.capturedStart();
            int length = match.capturedLength();
            QTextCharFormat format = rule.format;
            setFormat(start, length, format);
        }
    }

    // 先处理预处理命令
    QRegularExpressionMatchIterator preprocessorMatchIterator = preprocessorPattern.globalMatch(text);
    while (preprocessorMatchIterator.hasNext()) {
        QRegularExpressionMatch match = preprocessorMatchIterator.next();
        int start = match.capturedStart();
        int length = match.capturedLength();
        setFormat(start, length, preprocessorFormat);
    }

    //处理搜索文本高亮
    QRegularExpressionMatchIterator matches = searchPattern.globalMatch(text);
    QTextCharFormat highlightFormat;
    highlightFormat.setBackground(Qt::yellow);
    while (matches.hasNext())
    {
        QRegularExpressionMatch match = matches.next();
        setFormat(match.capturedStart(), match.capturedLength(), highlightFormat);
    }

   //处理调试信息高亮
    if(showErrorHighLight)
        for (const auto &info : errorInfo)
        {
            if (info.first.first == currentLineNumber + 1) {
                setFormat(0, text.length(), debugFormat);
                break;
            }
        }
}

/*//光标所处行高亮
void SyntaxHighlighter::setHighlightLine(int lineNumber)
{
    highlightLineNumber = lineNumber;
    rehighlight();
}

//查找时高亮
void SyntaxHighlighter::setSearchText(const QString &text)
{
    searchText = text;
    searchPattern.setPattern(searchText);
    searchPattern.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
    rehighlight();
}
*/
//显示错误时高亮
void SyntaxHighlighter::setDebugInfo(const std::vector <std::pair<std::pair<int, int>, QString> > &info)
{
    //std::cout << "Debug" << std::endl;
    this->errorInfo = info;
    showErrorHighLight = 1;
    rehighlight();
}
